#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <getopt.h>
#include <unistd.h>

int create_client_udp_socket()
{
    int sockfd;

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        return -1;
    }

    return sockfd;
}

extern char *optarg;
extern int optind, opterr, optopt;

char *l_opt_arg;
char* const short_options = "i:p:";
struct option long_options[] = {
  {"ip", required_argument, 0, 'i'},
  {"port", required_argument, 0, 'p'},
};

int main(int argc, char * argv[])
{
    int fds[16] = {-1};
    int fd_max = -1;
    int socketfd = -1;
    struct sockaddr_in destaddr;

    int ret = 0;
    char input[5*1024] = {0};

    int fd = open("/proc/bus/input/devices", O_RDWR);
    int len = read(fd, input, 5*1024);
    close(fd);
    char *p;
    p = input;
    int j = 0;

    char *remote_input_ip;
    int remote_input_port;

    char buff[1024];
    int size = 0;

    int c;
    while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1)
    {
        switch (c)
        {
        case 'i':
            remote_input_ip = optarg;
            break;
        case 'p':
            remote_input_port = atoi(optarg);
            break;

        default:
            return -1;
        }
    }

    printf("ip %s\n", remote_input_ip);
    printf("port %d\n", remote_input_port);

    socketfd = create_client_udp_socket();
    memset(&destaddr, 0, sizeof(struct sockaddr));

    destaddr.sin_family = AF_INET;
    destaddr.sin_port = htons(remote_input_port);
    destaddr.sin_addr.s_addr = inet_addr(remote_input_ip);
    bzero(&(destaddr.sin_zero), 0);

    if(socketfd == -1)
    {
        printf("create client socket faild \n");
        return -1;
    }
    struct timeval select_timeout;
    fd_set readfds;
    select_timeout.tv_sec= 4;
    select_timeout.tv_usec = 0;
    for(; p != NULL; j++)
    {
        p = strstr(p, "event");
        if (p)
        {
            char dev[24] =  "/dev/input/";
            int len = strstr(p, "\n")- p -1;
            printf("len %d\n", len);
            memcpy(dev + 11, p, len);
            printf("%s\n", dev);
            p += len;

            fds[j] = open(dev, O_RDWR);
            printf("fds[%d] = %d \n", j, fds[j]);
            if(fds[j] > fd_max)
                fd_max = fds[j];
            memset(dev+11, 0, 8);
        }
        else break;
    }

    int i = 0;
    while(1)
    {
        FD_ZERO(&readfds);
        select_timeout.tv_sec= 2;
        select_timeout.tv_usec = 0;
        for(i=0; i<j; i++)
        {
            //printf("i= %d j = %d fds[i]=%d \n", i,j, fds[i]);
            FD_SET(fds[i], &readfds);
        }
        ret = select(fd_max + 1, &readfds, NULL, NULL, &select_timeout);
        printf("ret = %d\n", ret);
        if(ret > 0)
        {
            for(i=0; i<j; i++)
            {
                if ( FD_ISSET(fds[i], &readfds))
                {
                    printf("begin to read event %d\n", i);
                    size = read(fds[i], &buff, 1024);

                    if (size <= 0)
                        continue;

                    if (sendto(socketfd, buff, size, 0, (struct sockaddr *)&destaddr, sizeof(struct sockaddr)) < 0)
                        printf("sendto error\n");
                    else
                        printf("sendto ok\n");
                }
            }
        }
        else
            printf("select time out \n");
    }
    for(i=0; i<j; i++)
    {
        close(fds[i]);
    }
    close(socketfd);
    return 0;
}
